package helper;
import java.awt.*;
import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import view.Board;
 
public class BubbleFactory {
 
    private static final int X = 10;
    private static final int Y = 10;
    private static final int BORDER_HORIZONTAL = 15;
    private static final int BORDER_VERTICAL = 10;
    private static final double CORNER_ARC_HORIZONTAL_PERCENTAGE = 0.55;
    private static final double CORNER_ARC_VERTICAL_PERCENTAGE = 0.35;
    private static final double FONT_VERTICAL_OFFSET_PERCENTAGE = 0.15;
    private static int BUBBLE_MIN_WIDTH = 100;
 
    private static final int LIP_WIDTH = 10;
    private static final int LIP_HEIGHT = 15;
    private static final int LIP_OFFSET = 15;
 
    /**
     * Method to draw a speech bubble with string
     * @param text
     * @return
     */
    public static Image buildBubbleWithString(String text) {
 
        // first buffered image for calculations
        BufferedImage calcImage = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
        Graphics2D calcg2d = (Graphics2D)calcImage.getGraphics();
 
        // text and border calculations
        String[] lines = text.split("\n");
        int textHeight = calcg2d.getFontMetrics().getHeight();
        int textHeightTotal = textHeight * lines.length;
        int textWidthTotal = 0;
        for (String s : lines) {
            int lineWidth = calcg2d.getFontMetrics().stringWidth(s);
            textWidthTotal = Math.max(lineWidth, textWidthTotal);
        }
 
        int borderWidth = Math.max((2 * BORDER_HORIZONTAL) + textWidthTotal, BUBBLE_MIN_WIDTH);
        int borderHeight = (2 * BORDER_VERTICAL) + textHeightTotal;
        int arcHorizontal = (int)(borderWidth * CORNER_ARC_HORIZONTAL_PERCENTAGE);
        int arcVertical = (int)(borderWidth * CORNER_ARC_VERTICAL_PERCENTAGE);
 
        // actual buffered image
        BufferedImage resultImage = new BufferedImage(X + borderWidth + 10, Y + borderHeight + 50, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = (Graphics2D)resultImage.getGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 
        // border
        Shape roundRectangle = new RoundRectangle2D.Double(X, Y, borderWidth, borderHeight, arcHorizontal, arcVertical);
        g2d.setColor(Color.WHITE);
        g2d.fill(roundRectangle);
        g2d.setColor(Color.BLACK);
        g2d.draw(roundRectangle);
 
        // text
        int verticalOffset = (int)(textHeight * FONT_VERTICAL_OFFSET_PERCENTAGE);
        for (int i = 0; i < lines.length; i++) {
            String line = lines[i];
            int lineWidth = g2d.getFontMetrics().stringWidth(line);
            int x = X + (borderWidth / 2) - (lineWidth / 2);
            int y = Y + BORDER_VERTICAL + (textHeight * (i + 1)) - verticalOffset;
            g2d.drawString(line, x, y);
        }
 
        // lip
        Path2D.Double path = new Path2D.Double();
 
        int lipX = X + (borderWidth / 2) - LIP_OFFSET;
        int lipY = Y + borderHeight;
 
        path.moveTo(lipX, lipY);
        path.lineTo(lipX - LIP_WIDTH, lipY + LIP_HEIGHT);
        path.lineTo(lipX - LIP_WIDTH, lipY);
 
        g2d.setColor(Color.WHITE);
        g2d.fill(path);
        g2d.setColor(Color.BLACK);
        g2d.draw(path);
 
        return resultImage;
 
    }
    
    /**
     * Method to draw a speech bubble with Images
     * @param board 
     * @param text
     * @return
     */
    public static Image buildBubbleWithImages(ArrayList<Image> images, Board board) {
    	BUBBLE_MIN_WIDTH=32*images.size();
        // images and border calculations
        int textHeight = 10;
        int textHeightTotal = textHeight * 2;
        int textWidthTotal = 0;
        for (Image image : images) {
            int lineWidth = image.getWidth(board);
            textWidthTotal = textWidthTotal+lineWidth;
        }
 
        int borderWidth = Math.max((2 * BORDER_HORIZONTAL) + textWidthTotal, BUBBLE_MIN_WIDTH);
        int borderHeight = (2 * BORDER_VERTICAL) + textHeightTotal;
        int arcHorizontal = (int)(borderWidth * CORNER_ARC_HORIZONTAL_PERCENTAGE);
        int arcVertical = (int)(borderWidth * CORNER_ARC_VERTICAL_PERCENTAGE);
 
        // actual buffered image
        BufferedImage resultImage = new BufferedImage(X + borderWidth + 10, Y + borderHeight + 50, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = (Graphics2D)resultImage.getGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 
        // border
        Shape roundRectangle = new RoundRectangle2D.Double(X, Y, borderWidth, borderHeight, arcHorizontal, arcVertical);
        g2d.setColor(Color.WHITE);
        g2d.fill(roundRectangle);
        g2d.setColor(Color.BLACK);
        g2d.draw(roundRectangle);
 
        // images
        int x = 0;
        for (int i=0;i<images.size();i++) {
           int y = 15;
           x = x+images.get(i).getWidth(board);
           g2d.drawImage(images.get(i), x, y,board);
		}
 
        // lip
        Path2D.Double path = new Path2D.Double();
 
        int lipX = X + (borderWidth / 2) - LIP_OFFSET;
        int lipY = Y + borderHeight;
 
        path.moveTo(lipX, lipY);
        path.lineTo(lipX - LIP_WIDTH, lipY + LIP_HEIGHT);
        path.lineTo(lipX - LIP_WIDTH, lipY);
 
        g2d.setColor(Color.WHITE);
        g2d.fill(path);
        g2d.setColor(Color.BLACK);
        g2d.draw(path);
 
        return resultImage;
    }
 
}
